package com.h2.ref.server.user.relationship.dao;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.h2.com.thoughtworks.xstream.converters.reflection.FieldDictionary;
import com.h2.com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.h2.ref.server.user.dao.UserDaoXml;
import com.h2.ref.server.user.relationship.UserRelationship;
import com.h2.util.resource.IResourceManager;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
import com.thoughtworks.xstream.io.xml.XppDriver;


public class UserRelationshipDaoInXml extends UserRelationshipDaoInMem {
   
   private static final Logger LOG = LoggerFactory.getLogger(
         UserDaoXml.class);
   
   ////
   
   private IResourceManager _resourceManager;
   
   private String _fileDir;
   
   private String _fileName = "user_relationship";
   
   private String _fileExt = ".xml";
   
   private Boolean _writeToFile = true;
   
   ////
   ////
   
   public void init() {
      super.init();
      Collection<UserRelationship> resultsFromFile = read();
      if(resultsFromFile != null) {
         for (UserRelationship item : resultsFromFile) {
            super.create(item);
         }
      }
   }
   
   @Override
   public Boolean create(UserRelationship relationship) {
      Boolean result = super.create(relationship);
      write();
      return result;
   }
   
   @Override
   public Boolean delete(UserRelationship relationship) {
      Boolean result = super.delete(relationship);
      write();
      return result;
   }
   
   public synchronized void write() {
      if (!getWriteToFile()) {
         return;
      }
      LOG.info("Writting DAO.");
      
      File file = new File(getFileDir(), getFileName() + getFileExt());
      
      XStream xstream = new XStream(null, new XppDriver(
            new XmlFriendlyReplacer("_-", "")));
      applyAlias(xstream);
      
      String xml = xstream.toXML(new ArrayList<UserRelationship>(
            getRelationships().values()));
      
      FileOutputStream fos = null;
      try {
         fos = new FileOutputStream(file);
         
         fos.write(xml.getBytes());
         fos.flush();
         fos.close();
         
         LOG.debug("File has been saved: " + file);
      } catch (IOException exp) {
         LOG.error(exp.getMessage());
         LOG.debug("Details: ", exp);
      }
   }
   
   @SuppressWarnings("unchecked")
   public Collection<UserRelationship> read() {
      LOG.info("Loading DAO.");
      
      File file = new File(getFileDir(), getFileName() + getFileExt());
      if(!file.exists()) {
         LOG.info("File does not exist: " + file);
         return null;
      }
      
      InputStream fis = null;
      XStream xstream = new XStream(
            new PureJavaReflectionProvider(new FieldDictionary()),
            new XppDriver(new XmlFriendlyReplacer("_-", "")));
      applyAlias(xstream);
      
      Collection<UserRelationship> results = null;
      try {
         fis = getResourceManager().getResource(file);
         results = (Collection<UserRelationship>)xstream.fromXML(fis);
         LOG.debug("DAO has been loaded: " + file);
         return results;
      } catch (IOException exp) {
         LOG.error(exp.getMessage());
         LOG.error("Details: ", exp);
         return null;
      }
   }
   
   private void applyAlias(XStream xstream) {
      xstream.alias("userRelationship", UserRelationship.class);
   }

   /**
    * @return the resourceManager
    */
   public IResourceManager getResourceManager() {
      return _resourceManager;
   }

   /**
    * @param resourceManager the resourceManager to set
    */
   public void setResourceManager(IResourceManager resourceManager) {
      _resourceManager = resourceManager;
   }

   /**
    * @return the fileDir
    */
   public String getFileDir() {
      return _fileDir;
   }

   /**
    * @param fileDir the fileDir to set
    */
   public void setFileDir(String fileDir) {
      _fileDir = fileDir;
   }

   /**
    * @return the fileName
    */
   public String getFileName() {
      return _fileName;
   }

   /**
    * @param fileName the fileName to set
    */
   public void setFileName(String fileName) {
      _fileName = fileName;
   }

   /**
    * @return the fileExt
    */
   public String getFileExt() {
      return _fileExt;
   }

   /**
    * @param fileExt the fileExt to set
    */
   public void setFileExt(String fileExt) {
      _fileExt = fileExt;
   }

   /**
    * @return the writeToFile
    */
   public Boolean getWriteToFile() {
      return _writeToFile;
   }

   /**
    * @param writeToFile the writeToFile to set
    */
   public void setWriteToFile(Boolean writeToFile) {
      _writeToFile = writeToFile;
   }
   
   

}
